package com.rivues.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.mail.MessagingException;
import javax.mail.internet.AddressException;
import javax.servlet.http.HttpServletRequest;
import javax.swing.text.html.HTML.Tag;

import org.apache.commons.io.FileUtils;
import org.apache.commons.jexl2.JexlEngine;
import org.apache.hadoop.io.MD5Hash;
import org.apache.http.HttpVersion;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.shiro.util.StringUtils;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.jasypt.util.text.BasicTextEncryptor;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.rivu.tools.TempletLoader;
import org.rivu.tools.TempletTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import SQLinForm_200.SQLForm;

import com.googlecode.aviator.AviatorEvaluator;
import com.rivues.core.RivuDataContext;
import com.rivues.module.datamodel.web.handler.DefaultParam;
import com.rivues.module.platform.web.bean.TaskInfo;
import com.rivues.module.platform.web.model.AnalyzerReport;
import com.rivues.module.platform.web.model.AnalyzerReportModel;
import com.rivues.module.platform.web.model.Auth;
import com.rivues.module.platform.web.model.Cube;
import com.rivues.module.platform.web.model.CubeLevel;
import com.rivues.module.platform.web.model.DataDic;
import com.rivues.module.platform.web.model.Dimension;
import com.rivues.module.platform.web.model.JobDetail;
import com.rivues.module.platform.web.model.Organ;
import com.rivues.module.platform.web.model.PublishedCube;
import com.rivues.module.platform.web.model.QueryLog;
import com.rivues.module.platform.web.model.ReportFilter;
import com.rivues.module.platform.web.model.ReportOperations;
import com.rivues.module.platform.web.model.RivuSite;
import com.rivues.module.platform.web.model.Role;
import com.rivues.module.platform.web.model.SearchResultTemplet;
import com.rivues.module.platform.web.model.User;
import com.rivues.module.platform.web.model.UserOrgan;
import com.rivues.module.platform.web.model.UserRole;
import com.rivues.module.platform.web.model.warning.EventBean;
import com.rivues.module.report.web.model.PublishedReport;
import com.rivues.module.report.web.model.TaskReport;
import com.rivues.module.report.web.model.TaskReportInfo;
import com.rivues.util.data.FirstTitle;
import com.rivues.util.data.Level;
import com.rivues.util.data.ReportData;
import com.rivues.util.data.ValueData;
import com.rivues.util.datasource.CubeTools;
import com.rivues.util.function.Function;
import com.rivues.util.function.impl.DateFunction;
import com.rivues.util.iface.cube.CubeFactory;
import com.rivues.util.iface.report.R3Request;
import com.rivues.util.iface.report.ReportFactory;
import com.rivues.util.local.LocalTools;
import com.rivues.util.mail.MailInfo;
import com.rivues.util.mail.MailSender;
import com.rivues.util.serialize.JSON;
import com.rivues.util.service.ServiceHelper;
import com.rivues.util.service.cache.CacheHelper;
import com.rivues.util.service.system.DataPersistenceService;
import com.rivues.util.sms.MessageFactory;
import com.rivues.util.sms.MessageSend;
import com.rivues.util.tools.ExportFile;
import com.rivues.util.tools.FileUtil;
import com.rivues.util.tools.RivuExcelUtil;
import com.rivues.util.tools.RuntimeData;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

@SuppressWarnings("rawtypes")
public class RivuTools {
	private final Logger log = LoggerFactory.getLogger(RivuTools.class); 
	private static SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
	public static Map<String, String> fieldMap = new HashMap();

	private static HttpClient httpclient = initHttpClientPool();

	private static SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
	private static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	private static final JexlEngine jexl = new JexlEngine();
    static {
       jexl.setCache(512);
       jexl.setLenient(false);
       jexl.setSilent(false);
    }
	private static HttpClient initHttpClientPool() {
		HttpParams params = new BasicHttpParams();
		HttpConnectionParams.setConnectionTimeout(params, 40000);
		HttpConnectionParams.setSoTimeout(params, 40000);
		ConnManagerParams.setMaxTotalConnections(params, 5);
		HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);

		SchemeRegistry schemeRegistry = new SchemeRegistry();
		schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
		schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));

		ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);
		return new DefaultHttpClient(cm, params);
	}

	public static boolean isSystemField(String field) {
		return (field != null) && (fieldMap.get(field.toLowerCase()) != null);
	}

	public static String getAnalyzerTime(int ta) {
		Calendar c = Calendar.getInstance();
		c.add(5, -ta);
		Date monday = c.getTime();
		String preMonday = sdf.format(monday);
		return preMonday;
	}

	public static String getAnalyzerFirstDay() {
		Calendar c = Calendar.getInstance();
		c.set(5, c.getActualMinimum(5));
		return sdf.format(c.getTime());
	}

	public static String getRegexGroup(String text, String regex) {
		String value = null;
		Matcher matcher = Pattern.compile(regex).matcher(text);
		if ((matcher.find()) && (matcher.groupCount() >= 1)) {
			value = matcher.group(1);
		}
		return value;
	}
	/**
	 * 根据异常获取异常信息
	 * @param e
	 * @return
	 */
	public static String getExceptionMessage(Exception e) {
		String s = "";
		for (int i = 0; i < e.getStackTrace().length; i++) {
			if(i==0){
				s+=e.toString();
			}
			s+="\\n	"+e.getStackTrace()[i].toString();
		}
		return s;
	}

	public static String md5(String str) {
		return String.valueOf(MD5Hash.digest(str).halfDigest()).replace("-", "a");
	}

	public static String getId(String str) {
		return md5(str);
	}


	public static byte[] toBytes(Object object) throws Exception {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		ObjectOutputStream objectOutput = new ObjectOutputStream(out);
		objectOutput.writeObject(object);
		return out.toByteArray();
	}

	public static Object toObject(byte[] data) throws Exception {
		ByteArrayInputStream input = new ByteArrayInputStream(data);
		ObjectInputStream objectInput = new ObjectInputStream(input);
		return objectInput.readObject();
	}

	public static String getURL(String url, String param) {
		StringBuffer strb = new StringBuffer().append(url);
		if (param != null && param.length() > 0) {
			strb.append("?").append(param);
		}
		HttpGet httpget = new HttpGet(strb.toString());
		try {
			ResponseHandler responseHandler = new BasicResponseHandler();
			return (String) httpclient.execute(httpget, responseHandler);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return "";
	}

	public static String getURL(String url) {
		return getURL(url, null);
	}

	public static String postData(String url, List<NameValuePair> nvps) {
		HttpPost httpost = new HttpPost(url);
		try {
			httpost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
			ResponseHandler responseHandler = new BasicResponseHandler();
			return (String) httpclient.execute(httpost, responseHandler);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return "";
	}
	/**
	 * 日期转换到字符串
	 * @param 	paramDate		要转换的日期
	 * @param 	pattern			转换格式：例：yyyy-MM-dd
	 * @return	String			日期字符串
	 */
	public static String dateToString(Date paramDate, String pattern)
	{
		DateFormat sdf = new SimpleDateFormat(pattern);
		return sdf.format(paramDate);
	}
	
	/**
	 * 
	 * @param pattern
	 * @return
	 */
	public static Date stringToDate(String dataStr)throws Exception{
		return format.parse(dataStr);
	}
	/**
	 * 
	 * @param job
	 * @return
	 */
	public static List <NameValuePair> createNamePair(Object data){
		List<NameValuePair> nvps=new ArrayList<NameValuePair>();  
		nvps.add(new BasicNameValuePair("sign", "")) ;
		nvps.add(new BasicNameValuePair("data", JSON.toJSONString(data))) ;
		return nvps ;
	}

	/**
	 * 根据ID或代码获取模板
	 * @param code
	 * @return
	 */
	public static SearchResultTemplet getSearchResultTemplet(String code){
		List<SearchResultTemplet> tableViewList = RivuDataContext.getService().findAllByCriteria(DetachedCriteria.forClass(SearchResultTemplet.class).add(Restrictions.or(Restrictions.eq("name", code), Restrictions.or(Restrictions.eq("id", code), Restrictions.eq("code", code))) ));
		return tableViewList.size()>0?tableViewList.get(0) : null;
		
	}
	/**
     * 
     * @param templetid
     * @throws IOException 
     * @throws TemplateException 
     */
    public static String getTemplet(SearchResultTemplet resultTemplet , Map<String , Object> values) throws IOException, TemplateException{
    	StringWriter writer = new StringWriter(); 
		Configuration cfg = null;
		Template template = null ;
		if(resultTemplet!=null){
			cfg = new Configuration();
			TempletLoader loader = new TempletLoader(resultTemplet.getTemplettext()!=null ? resultTemplet.getTemplettext() : "") ;
			cfg.setTemplateLoader(loader);   
			cfg.setDefaultEncoding("UTF-8");  
			template = cfg.getTemplate("");
			template.process(values, writer);  
		}
		return writer.toString() ;
    }
    
    /**
     * 
     * @param templetid
     * @throws IOException 
     * @throws TemplateException 
     */
    public static String getTemplet(String templet , Map<String , Object> values) throws IOException, TemplateException{
    	StringWriter writer = new StringWriter(); 
		Configuration cfg = null;
		Template template = null ;
		String retValue = templet ;
		if(templet!=null && templet.length()>0 && templet.indexOf("$")>=0){
			cfg = new Configuration();
			TempletLoader loader = new TempletLoader(templet) ;
			cfg.setTemplateLoader(loader);   
			cfg.setDefaultEncoding("UTF-8");  
			template = cfg.getTemplate("");
			template.process(values, writer);  
			retValue = writer.toString() ;
		}
		return  retValue;
    }
    /**
     * 
     * @param query
     * @return
     */
    public static String formatQuery(String query){
    	SQLForm form = new SQLForm();
		form.setCase(false, false);
		form.setLowerCase(false);
		form.setGraphLevel(false);
		form.setSuppressSpace(true);
		form.setQuoteCharacter("'");
		form.setSuppressEmptyLine(true);
		form.setFormatLanguage("SQL");
		form.setBracketSpaces("noSpacesAroundBracket");
		form.setCommaSpaces("oneSpaceAfterComma");
		form.setEqualSpaces("oneSpaceAroundEqual");
		form.setSmallSQLWidth(100);
		form.setPageWidth(100);
		form.setAndOrIndention(true);
		form.setInitialIndentation(0);
		return form.formatSQLAsString(query) ;
    }
    
    public static String getInx2Char(int num){
		int level = num ;
		StringBuffer strb = new StringBuffer() ;
		while( level/26 >= 26){
			strb.append((char)((level / 26)%26+65));
			if(level/26 == 1){
				level = level % 26 ;
			}else{
				level = level / 26 + level % 26;
			}
		}
		if(level/26 >0){
			if(level/26==0){
				strb.append((char)(65));
			}else{
				strb.append((char)(level/26+64));
			}
			level = level % 26 ;
		}
		strb.append((char)(level+65)) ;
		
		
		return strb.toString();
	}
    
    public static int getChar2Inx(String chr){
    	int inx = 0 ;
		for(int i=0  ; i<chr.length() ; i ++){
			char inxchr = chr.charAt(i) ;
			inx = inx + (inxchr - 65) ;
		}
		return inx ;
	}
    /**
     * 自动生成代码
     * @return
     */
    public static String getCode(){
    	return new StringBuffer().append("RIVU_").append(System.currentTimeMillis()).toString() ;
    }
    /**
     * 表达式引擎
     * @return
     */
    public static JexlEngine getJexlEngine(){
    	return jexl ;
    }
    private static SolrServer solrServer ;
    /**
     * 
     * @return
     */
    public static SolrServer getSolrServer(){
    	return solrServer==null ? solrServer = new EmbeddedSolrServer(RivuDataContext.getCorecontainer().getCore("log")) : solrServer ;
//    	return solrServer==null ? solrServer = new HttpSolrServer("http://127.0.0.1:8983/solr/collection1") : solrServer ;
    }
    /**
     * 
     * @param str
     * @return
     * @throws NoSuchAlgorithmException 
     */
    public static String encryption(String str) throws NoSuchAlgorithmException{
    	BasicTextEncryptor  textEncryptor = new BasicTextEncryptor ();
    	textEncryptor.setPassword(RivuDataContext.getSystemSecrityPassword());
    	return textEncryptor.encrypt(str);
    }
    
    /**
     * 
     * @param str
     * @return
     * @throws NoSuchAlgorithmException 
     */
    public static String decryption(String str) throws NoSuchAlgorithmException{
    	BasicTextEncryptor  textEncryptor = new BasicTextEncryptor ();
    	textEncryptor.setPassword(RivuDataContext.getSystemSecrityPassword());
    	return textEncryptor.decrypt(str);
    }
    
    /**
	 * 
	 * @param plan
	 * @return
	 */
	public static String convertCrond(TaskInfo plan){
		StringBuffer strb = new StringBuffer() ;
		if("day".equals(plan.getRunCycle())){
			strb.append(plan.getRunBeginSecond()).append(" ").append(plan.getRunBeginMinute()).append(plan.getIsRepeat() && plan.getRepeatSpace()!=null && plan.getRepeatSpace()<60 ? "/"+ plan.getRepeatSpace() : "").append(" ").append(plan.getRunBeginHour()).append(plan.getIsRepeat() && plan.getRepeatSpace()!=null ? "-23" : "").append(" ").append("*").append(plan.getRunSpace() != null && plan.getRunSpace()>0 ? "/"+plan.getRunSpace():"").append(" ").append(" * ?") ;
		}
		if("week".equals(plan.getRunCycle())){
			strb.append(plan.getRunBeginSecond()).append(" ").append(plan.getRunBeginMinute()).append(plan.getIsRepeat() && plan.getRepeatSpace()!=null && plan.getRepeatSpace()<60 ? "/"+ plan.getRepeatSpace() : "").append(" ").append(plan.getRunBeginHour()).append(plan.getIsRepeat() && plan.getRepeatSpace()!=null ? "-23" : "").append(" ").append(plan.getRunDates()==null || plan.getRunDates().length==0 ? "*":"?").append(" * ").append(plan.getRunDates()==null || plan.getRunDates().length==0? "?" : StringUtils.toString(plan.getRunDates())).append(plan.getRunSpace()!=null && plan.getRunSpace()>0 ? "/"+plan.getRunSpace(): "") ;
		}
		if("month".equals(plan.getRunCycle())){
			strb.append(plan.getRunBeginSecond()).append(" ").append(plan.getRunBeginMinute()).append(plan.getIsRepeat() && plan.getRepeatSpace()!=null && plan.getRepeatSpace()<60 ? "/"+ plan.getRepeatSpace() : "").append(" ").append(plan.getRunBeginHour()).append(plan.getIsRepeat() && plan.getRepeatSpace()!=null ? "-23" : "").append(" ").append(plan.getRunBeginDate()).append(" ").append(plan.getRunDates()==null || plan.getRunDates().length==0? "*" : StringUtils.toString(plan.getRunDates())).append(" ").append(" ?") ;
		}
		return strb.toString() ;
	}
	/***
	 * 计算T+1
	 * @param text
	 * @param format
	 * @return
	 */
	public static String getDays(String text , String format){
		String retDateFormat = text ;
		Pattern pattern = Pattern.compile("[ ]{0,}([TtMmYy]{1,})[ ]{0,}[+-]{0,1}([\\d]{0,})") ;
    	Matcher matcher = pattern.matcher(text) ;
    	if(matcher.find() && matcher.groupCount()>=1){
    		try {
    			if(matcher.group(1) .equalsIgnoreCase("T")){
    				retDateFormat = RivuTools.formatDateValue(format, RivuTools.getDaysParam(text)) ;
    			}else if(matcher.group(1) .equalsIgnoreCase("M")){
    				retDateFormat = RivuTools.formatMonthValue(format, RivuTools.getDaysParam(text)) ;
    			}else if(matcher.group(1) .equalsIgnoreCase("Y")){
    				retDateFormat = String.valueOf((int)Double.parseDouble(String.valueOf(RivuTools.getDaysParam(text))));
    			}
			} catch (ParseException e) {
				e.printStackTrace();
			}
    	}
    	return retDateFormat ;
	}
	
	/***
	 * 计算T+1
	 * @param text
	 * @param format
	 * @return
	 */
	public static Object getDaysParam(String text){
		Map<String,Object>  context = new HashMap<String,Object>();
		context.put("T", processDays()) ;
		context.put("t", processDays()) ;
		context.put("M", processMonth()) ;
		context.put("m", processMonth()) ;
		context.put("Y", processYear()) ;
		context.put("y", processYear()) ;
		
    	return AviatorEvaluator.execute(text , context) ;
	}
	/**
	 * 
	 * @param defaultParam
	 * @param value
	 * @return
	 * @throws ParseException 
	 * @throws Exception 
	 */
	public static String formatDateValue(DefaultParam defaultParam , Object value) throws ParseException{
		if(value!=null && defaultParam.isUserdate() && value.toString().matches("[\\d.]{5,}")){
			value = new SimpleDateFormat(defaultParam.getFormat()).format(new Date((long)(Double.parseDouble(value.toString())*24*60*60*1000))) ;
		}
		return value!=null ? value.toString() : "0" ;
	}
	
	/**
	 * 
	 * @param defaultParam
	 * @param value
	 * @return
	 * @throws ParseException 
	 * @throws Exception 
	 */
	public static String formatDateValue(String format , Object value) throws ParseException{
		if(value!=null && value.toString().matches("[\\d.]{5,}")){
			value = new SimpleDateFormat(format).format(new Date((long)(Double.parseDouble(value.toString())*24*60*60*1000))) ;
		}
		return value!=null ? value.toString() : "0" ;
	}
	/**
	 * 
	 * @param defaultParam
	 * @param value
	 * @return
	 * @throws ParseException 
	 * @throws Exception 
	 */
	public static String formatMonthValue(String formatValue , Object value) throws ParseException{
		if(value!=null && value.toString().matches("[\\d.]{3,}")){
			int months = (int)Double.parseDouble(String.valueOf(value));
			int year = 0 ;
			int month = 0 ;
			if(months%12==0){
				year = months/12 - 1 ;
				month = 12 ;
			}else{
				year = months/12 ;
				month = months % 12 ;
			}
			if(month<10){
				value = String.valueOf(year)+"0"+String.valueOf(month) ;
			}else{
				value = String.valueOf(year)+ String.valueOf(month) ;
			}
			value = new SimpleDateFormat(formatValue).format(new SimpleDateFormat("yyyyMM").parse(String.valueOf(value)));
		}
		return value!=null ? value.toString() : "0" ;
	}
	/**
	 * 
	 * @return
	 */
	public static double processDays(){
		return System.currentTimeMillis()*1.0f/(1000*60*60*24);
	}
	
	/**
	 * 
	 * @return
	 */
	public static double processMonth(){
		Calendar calendar = Calendar.getInstance() ;
		int month = calendar.get(Calendar.YEAR)*12 + calendar.get(Calendar.MONTH )+1 ;
		return month;
	}
	
	/**
	 * 
	 * @return
	 */
	public static double processYear(){
		return  Calendar.getInstance() .get(Calendar.YEAR);
	}
	
	/**
	 * 获取默认的 参数
	 * @param filter
	 * @return
	 */
	public static String getDefaultValue(ReportFilter filter , String vtype , HttpServletRequest request){
		String defaultValue = filter.getDefaultvalue();
		try {
			if(defaultValue!=null && defaultValue.length()>0 && defaultValue.indexOf("$")>=0){
				defaultValue = RivuTools.getTemplet(filter.getDefaultvalue(), getRequestParamValue(request));
			}
			if(defaultValue!=null && defaultValue.matches("[ ]{0,}[TtMmYy]{1,}[ ]{0,}[+-]{0,1}([\\d]{0,})")){//处理动态参数的问题 ， Y表示 年 ， 如 Y+1 ， M表示 月 ， 如：M+1 ， T表示 日 ， 如 T+1 ， 例如，Y-1 = 2013 ， M-1 = 8
				defaultValue = processParam(filter.getFormatstr() , defaultValue);
			}
			if(defaultValue!=null && defaultValue.trim().startsWith("function:")){//处理函数
				defaultValue = processContent(defaultValue,null,true);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TemplateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		String retValue = filter.getRequestvalue()!=null && !filter.getRequestvalue().equals(filter.getDefaultvalue()) && filter.getRequestvalue().length()>0 ? filter.getRequestvalue() : defaultValue;
		if(vtype!=null && vtype.equals(RivuDataContext.ReportCompareEnum.START.toString())){
			retValue = RivuTools.getStartValue(filter, request) ;
		}
		if(vtype!=null && vtype.equals(RivuDataContext.ReportCompareEnum.END.toString())){
			retValue = RivuTools.getEndValue(filter, request) ;
		}
		return retValue ;
	}
	/**
	 * 
	 * @param defaultFormatValue
	 * @param text
	 * @return
	 */
	public static String processParam(String defaultFormatValue, String text){
		String formatValue = "yyyy-MM-dd" ;
		if(text.matches("[ ]{0,}([Yy]{1,})[ ]{0,}[+-]{0,1}([\\d]{0,})")){
			formatValue = "yyyy" ;
		}else if(text.matches("[ ]{0,}([Mm]{1,})[ ]{0,}[+-]{0,1}([\\d]{0,})")){
			formatValue = "yyyy-MM" ;
		}
		
		return getDays(text, defaultFormatValue!=null && defaultFormatValue.length()>0 ? defaultFormatValue : formatValue) ;
	}
	
	/**
	 * 获取默认的 参数
	 * @param filter
	 * @return
	 * @throws TemplateException 
	 * @throws IOException 
	 */
	public static String getDefaultValue(ReportFilter filter , HttpServletRequest request){
		String value = filter.getDefaultvalue();
		try {
			value = filter.getRequestvalue()!=null && filter.getRequestvalue().length()>0 ? filter.getRequestvalue() : RivuTools.getTemplet(filter.getDefaultvalue(), getRequestParamValue(request));
			if(value!=null && value.trim().startsWith("function:")){//处理函数
				value = processContent(value,null,true);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (TemplateException e) {
			e.printStackTrace();
		}
		return value;
	}
	
	/**
	 * 获取默认的 参数
	 * @param filter
	 * @return
	 */
	public static String getStartValue(ReportFilter filter , HttpServletRequest request){
		String startValue = filter.getStartvalue();
		try {
			if(startValue!=null && startValue.length()>0 && startValue.indexOf("$")>=0){
				startValue = RivuTools.getTemplet(startValue, getRequestParamValue(request));
			}
			if(startValue!=null && startValue.matches("[ ]{0,}[TtMmYy]{1,}[ ]{0,}[+-]{0,1}([\\d]{0,})")){//处理动态参数的问题 ， Y表示 年 ， 如 Y+1 ， M表示 月 ， 如：M+1 ， T表示 日 ， 如 T+1 ， 例如，Y-1 = 2013 ， M-1 = 8
				startValue = processParam(filter.getFormatstr() , startValue);
			}
			if(startValue!=null && startValue.trim().startsWith("function:")){//处理函数
				startValue = processContent(startValue,null,true);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TemplateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return filter.getRequeststartvalue()!=null&&filter.getRequeststartvalue().length()>0 ? filter.getRequeststartvalue(): startValue  ;
	}
	
	/**
	 * 获取默认的 参数
	 * @param filter
	 * @return
	 */
	public static String getEndValue(ReportFilter filter , HttpServletRequest request){
		String endValue = filter.getEndvalue();
		try {
			if(endValue!=null && endValue.length()>0 && endValue.indexOf("$")>=0){
				endValue = RivuTools.getTemplet(endValue, getRequestParamValue(request));
			}
			if(endValue!=null && endValue.matches("[ ]{0,}[TtMmYy]{1,}[ ]{0,}[+-]{0,1}([\\d]{0,})")){//处理动态参数的问题 ， Y表示 年 ， 如 Y+1 ， M表示 月 ， 如：M+1 ， T表示 日 ， 如 T+1 ， 例如，Y-1 = 2013 ， M-1 = 8
				endValue = processParam(filter.getFormatstr() , endValue);
			}
			if(endValue!=null && endValue.trim().startsWith("function:")){//处理函数
				endValue = processContent(endValue,null,true);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TemplateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return 
			filter.getRequestendvalue()!=null&&filter.getRequestendvalue().length()>0 ? filter.getRequestendvalue() : endValue    ;
	}
	
	private static HashMap getRequestParamValue(HttpServletRequest request){
		HashMap<String, Object> values = new HashMap<String, Object>();
		if(request!=null && request.getSession()!=null){
			values.put("user", request.getSession().getAttribute(RivuDataContext.USER_SESSION_NAME)) ;
		}else{
			values.put("user", new User()) ;
		}
		return values ;
	}
	
	
	/**
	 * 
	 * @param input
	 * @return
	 * @throws UnsupportedEncodingException 
	 */
	public static String cvChar(String input) throws UnsupportedEncodingException{
		return java.net.URLEncoder.encode(input!=null ? input : "report","UTF-8") ;
	}
	
	/**
	 * 
	 * @param id
	 * @param userid
	 * @return
	 */
	public static String genReportCacheID(String id , User user , boolean userSessionID){
		return new StringBuffer().append(id).append("_").append(userSessionID? user.getSessionid() : user.getId()).toString();
	}
	/**
	 * 获取过滤器列表中的 非 静态参数
	 * @param filters
	 * @return
	 */
	public static List<ReportFilter> getRequestFilters(List<ReportFilter> filters){
		List<ReportFilter> tempFilters = new ArrayList<ReportFilter>() ;
		if(filters!=null){
			for(ReportFilter temp : filters){
				if(!temp.isRequest()){
					tempFilters.add(temp) ;
				}
			}
		}
		return tempFilters;
	}
	/**
	 * 获取过滤器列表中的 静态参数
	 * @param filters
	 * @return
	 */
	public static List<ReportFilter> getStaticFilters(List<ReportFilter> filters){
		List<ReportFilter> tempFilters = new ArrayList<ReportFilter>() ;
		if(filters!=null){
			for(ReportFilter temp : filters){
				if(temp.isRequest()){
					tempFilters.add(temp) ;
				}
			}
		}
		return tempFilters;
	}
	/**
	 * 根据用户获取用户已授权的  权限
	 * @param roleList
	 * @return
	 */
	public static List<Auth> getAuthListByRole(List<UserRole> roleList){
		List<Auth> authList = new ArrayList<Auth>();
		if(roleList!=null && roleList.size()>0){
			DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Auth.class).add(Restrictions.eq("resourcetype",Auth.RESOURCE_TYPE_MENU)) ;
			List<String> roleids = new ArrayList();
			for(UserRole role : roleList){
				roleids.add(role.getRoleid()) ;
			}
			detachedCriteria.add(Restrictions.in("ownerid", roleids)) ;
			authList = RivuDataContext.getService().findPageByCriteria(detachedCriteria) ;
		}
		return authList ;
	}
	
	/**
	 * 根据用户的角色列表
	 * @param roleList
	 * @return
	 */
	public static List<Role> getUserRoleList(User user , String orgi){
		List<Role> roleList = new ArrayList<Role>();
		if(user!=null && orgi!=null){
			DetachedCriteria detachedCriteria = DetachedCriteria.forClass(UserRole.class).add( Restrictions.eq("userid",user.getId())) ;
			detachedCriteria.add(Restrictions.eq("orgi", orgi)) ;
			List<UserRole> userRoleList = RivuDataContext.getService().findPageByCriteria(detachedCriteria) ;
			for(UserRole userRole : userRoleList){
				roleList.add(userRole.getRole()) ;
			}
			roleList.addAll(RivuDataContext.getService().findPageByCriteria(DetachedCriteria.forClass(Role.class).add( Restrictions.or(Restrictions.eq("name",RivuDataContext.ALL_USER_CH), Restrictions.eq("name",RivuDataContext.ALL_USER_CH))).add(Restrictions.eq("orgi",orgi)))) ;
		}
		return roleList ;
	}
	
	/**
	 * 根据用户的角色列表
	 * @param roleList
	 * @return
	 */
	public static List<Organ> getUserOrganList(User user , String orgi){
		List<Organ> organList = new ArrayList<Organ>();
		if(user!=null && orgi!=null){
			DetachedCriteria detachedCriteria = DetachedCriteria.forClass(UserOrgan.class).add(Restrictions.eq("userid",user.getId())) ;
			detachedCriteria.add(Restrictions.eq("orgi", orgi)) ;
			List<UserOrgan> userOrganList = RivuDataContext.getService().findPageByCriteria(detachedCriteria) ;
			Organ organ = null;
			for(UserOrgan userOrgan : userOrganList){
				if(!userOrgan.getOrganid().equals("0")){
					organ = (Organ)RivuDataContext.getService().getIObjectByPK(Organ.class, userOrgan.getOrganid());
					organList.add(organ) ;
				}
				
			}
		}
		return organList ;
	}
	/**
	 * 
	 * @param report
	 * @param model
	 * @param p
	 * @param ps
	 * @return
	 * @throws Exception
	 */
	public static ReportData getReportData(AnalyzerReport report , HttpServletRequest request, AnalyzerReportModel model  , int p , int ps) throws Exception{
		if(request==null){
			request = new R3Request();
			((R3Request)request).setParameters("p", String.valueOf(p)) ;
			((R3Request)request).setParameters("ps", String.valueOf(ps)) ;
		}else if(request instanceof R3Request){
			((R3Request)request).setParameters("p", String.valueOf(p)) ;
			((R3Request)request).setParameters("ps", String.valueOf(ps)) ;
		}
		return ServiceHelper.getReportService().service(request , model , report , true ,  new QueryLog()  , false , false)  ;
	}
	
	/**
	 * 
	 * @param report
	 * @param model
	 * @param p
	 * @param ps
	 * @return
	 * @throws Exception
	 */
	public static void getRSReportData(AnalyzerReport report , HttpServletRequest request, AnalyzerReportModel model  , int p , int ps , ExportFile export) throws Exception{
		if(request==null){
			request = new R3Request();
			((R3Request)request).setParameters("p", String.valueOf(p)) ;
			((R3Request)request).setParameters("ps", String.valueOf(ps)) ;
		}else if(request instanceof R3Request){
			((R3Request)request).setParameters("p", String.valueOf(p)) ;
			((R3Request)request).setParameters("ps", String.valueOf(ps)) ;
		}
		ServiceHelper.getReportService().service(request , model , report , true ,  new QueryLog()  , export)  ;
	}
	/**
	 * 发送邮件
	 * @param email
	 * @param cc
	 * @param subject
	 * @param content
	 * @throws Exception
	 */
	public static void sendMail(String email , String cc , String subject , String content ,List<String> filenames) throws Exception{
		List<RivuSite> siteList = RivuDataContext.getService().findAllByCriteria(DetachedCriteria.forClass(RivuSite.class).add(Restrictions.eq("groupid",RivuDataContext.NotifiactionType.EMAIL.toString()))) ;
		if(siteList.size()>0){
			RivuSite emailSite = siteList.get(0) ;
			MailSender sender = new MailSender(emailSite.getSmtpserver(),emailSite.getMailfrom(),emailSite.getSmtpuser(), decryption(emailSite.getSmtppassword()));
			if(email!=null){
				try{
					sender.send(email,cc, subject, content,filenames);
				}catch(Exception e){
					EventBean eventLog = new EventBean();
					RuntimeData runtimeData = new RuntimeData() ;
					eventLog.setHostname(runtimeData.getHostname()) ;
					eventLog.setIpaddr(runtimeData.getIpaddr()) ;
					eventLog.setDatatype(RivuDataContext.SystemInfoType.R3QUERY_V50_SERVER.toString());
					eventLog.setPort(runtimeData.getPort());
					eventLog.setEventype(RivuDataContext.EventType.NOEMAILCONFIG.toString()) ;
					eventLog.setEventmsg(LocalTools.getMessage("I_ERROR_5000001"));
					eventLog.setEventlevel(new StringBuffer().append(RivuDataContext.EventLevelType.ERROR.toString()).append("，错误消息如下：").append(e.getMessage()).toString()) ;
					DataPersistenceService.persistence(eventLog) ;
					e.printStackTrace();
				}
			}
		}else{
			throw new Exception("邮件发送失败，请配置邮件服务器。");
		}
	}
	
	/**
	 * 发送
	 * @param report
	 * @param emailSite
	 */
	public static void sendMessage(String receivers,String content,JobDetail job)throws Exception{
		MessageSend sender = MessageFactory.getInstance(job.getOrgi());
		String[] phones = receivers.split(",");
		for (String phone : phones) {
			sender.send(phone, content);
		}
	}
	
	public static String processFilterValue(String[] levels , TaskReportInfo taskReportInfo){
		String retValue = null ;
		if(taskReportInfo!=null && taskReportInfo.getReportList().size()>0){
			for(TaskReport taskReport : taskReportInfo.getReportList()){
				if(taskReport.getPublishedReport()!=null && levels[0].equals(taskReport.getPublishedReport().getName())){
					AnalyzerReport report = taskReport.getPublishedReport().getReport() ;
					for(ReportFilter filter : report.getFilters()){
						if(filter.getName().equals(levels[1])){
							retValue = RivuTools.getDefaultValue(filter, null) ;
							break ;
						}
					}
				}
			}
		}
		return retValue ;
	}
	/**
	 * 通用处理，根据 名称 或 序号 获取 model
	 * @param taskReportInfo
	 * @param reportname
	 * @param modelname
	 * @return
	 */
	public static AnalyzerReportModel getProcessReportModel(TaskReportInfo taskReportInfo , String reportname , String modelname){
		AnalyzerReportModel model = null ;
		for(TaskReport taskReport : taskReportInfo.getReportList()){
			if(taskReport.getPublishedReport()!=null && reportname.equals(taskReport.getPublishedReport().getName())){
				AnalyzerReport report = taskReport.getPublishedReport().getReport() ;
				if(modelname==null || modelname.matches("[\\d]{1,}")){
					int inx = modelname==null ? 0 : Integer.parseInt(modelname) ;
					if(report.getModel().size()>inx){
						model = report.getModel().get(inx) ;
					}
				}else{
					for(AnalyzerReportModel arm : report.getModel()){
						if(modelname.equals(arm.getTitle())){
							model = arm;
							break ;
						}
					}
				}

			}
		}
		return model ;
	}
	/**
	 * 根据参数获取 ReportData里的数据值
	 * @param levels
	 * @param taskReportInfo
	 * @return
	 */
	public static ValueData processParamValue(String[] levels, TaskReportInfo taskReportInfo){
		ValueData retValueData = null ;
		AnalyzerReportModel model = getProcessReportModel(taskReportInfo , levels[0] , levels.length >= 2 ? levels[1]: null ) ;
		if(model!=null && model.getReportData()!=null && model.getReportData().getData()!=null && model.getReportData().getData().size() > 0){
			List<ValueData> valueDataList = model.getReportData().getData().get(0) ;
			if(levels.length == 4){
				boolean nameFound = false ;
				for(List<ValueData> tempValueDataList : model.getReportData().getData()){
					if(tempValueDataList.size()>0 && tempValueDataList.get(0).getRow()!=null && tempValueDataList.get(0).getRow().getParent()!=null && tempValueDataList.get(0).getRow().getParent().getName().equals(levels[3])){
						valueDataList = tempValueDataList ;
						nameFound = true ;
						break ;
					}
				}
				if(!nameFound && levels[3].matches("[\\d]{1,}")){
					int rows = Integer.parseInt(levels[3]) ;
					if(rows<model.getReportData().getData().size()){
						valueDataList = model.getReportData().getData().get(rows) ;
					}
				}
			}
			if(levels.length>=3){
				for(ValueData valueData : valueDataList){
					if(valueData.getName().equals(levels[2]) || (levels[2].matches("[\\d]{1,}") && Integer.parseInt(levels[2]) == valueDataList.indexOf(valueData))){
						retValueData = valueData ;
						break ;
					}
				}
			}else{
				if(valueDataList.size()>0){
					retValueData = valueDataList.get(0) ;
				}
			}
		}
		return retValueData ;
	}
	
	public static String processContent(String content , TaskReportInfo taskReportInfo , boolean processhtml){
		/**
		 * 处理表格优先，表格处理完毕后再处理正文中的内容
		 */
		if(content==null) return "";
		
		content = processContentTable(content, taskReportInfo , processhtml);
		/**
		 * 表格替换完毕
		 */
		StringBuffer strb = new StringBuffer();
		Pattern pattern = Pattern.compile("(\\[[\\S\\s]*?\\])") ;
		Matcher matchers = pattern.matcher(content) ;
		int strindex = 0 ;
		while(matchers.find()){
			if(matchers.groupCount()>=1){
				String param = matchers.group(1).replaceAll("<[\\S\\s]*?>", "").replaceAll("[\\[\\]]*", "");
				/**
				 * param即为需要替换的参数
				 */
				String[] levels = param.split("\\.") ;
				if(levels.length>=1){
					String value = "";
					if(levels.length == 2){
						value = RivuTools.processFilterValue(levels, taskReportInfo) ;
						value = (value!=null ? value : "") ;
					}else{
						ValueData valueData = RivuTools.processParamValue(levels, taskReportInfo);
						value = valueData!=null ? valueData.getValueStyle()!=null ? valueData.getValueStyle() : valueData.getForamatValue()!=null ?valueData.getForamatValue():"": "";
					}
					strb.append(content.substring(strindex , matchers.start())).append(value) ;
				}
				strindex = matchers.end() ;
			}
		}
		strb.append(content.substring(strindex)) ;
		
		
		/**
		 * 表格、内容等都处理完毕后再处理表达式 ， 例如 {报表一.测试报表.指标一 + 报表二.测试报表.指标一}
		 */
		content =  processExpressContent(strb.toString(), taskReportInfo, processhtml) ;
		
		/**
		 * 处理文本里面的函数
		 */
		strb = new StringBuffer();
		pattern = Pattern.compile("function:[\\S\\s]*?\\)") ;
		matchers = pattern.matcher(content) ;
		strindex = 0 ;
		while(matchers.find()){
			String functionstr = matchers.group(0).replace("function:", "");
			if(functionstr.startsWith("reporthtml(")){
				try {
					strb.append(content.substring(strindex , matchers.start())).append(dealReportHtml(functionstr, taskReportInfo, matchers));
				} catch (Exception e) {
					e.printStackTrace();
					strb.append(content.substring(strindex , matchers.start())).append(matchers.group(0));
				}
			}else{
				Function function = getFunction(functionstr);
				if(function!=null){
					strb.append(content.substring(strindex , matchers.start())).append(function.excute(functionstr).toString()) ;
				}else{
					strb.append(content.substring(strindex , matchers.start())).append(matchers.group(0));
				}
			}
			
			strindex = matchers.end() ;
		}
		
		strb.append(content.substring(strindex)) ;
		/**
		 * 表格、内容等都处理完毕后再处理表达式 ， 例如 {报表一.测试报表.指标一 + 报表二.测试报表.指标一}
		 */
		return strb.toString();
	}
	public static String dealReportHtml(String functionstr,TaskReportInfo taskReportInfo,Matcher matchers){
		String result = null;
		functionstr = functionstr.replace("reporthtml(", "");
		functionstr = functionstr.replace(")", "");
		String[] params = functionstr.split(",");
		
		String reportname = params[0].trim();
		
		PublishedReport publishedReport = null;
		List<TaskReport> reportList = taskReportInfo.getReportList();
		if(reportList!=null&&reportList.size()>0){
			for (TaskReport taskReport : reportList) {
				if(reportname.equals(taskReport.getPublishedReport().getName())){
					publishedReport = taskReport.getPublishedReport();
				}
			}
		}
		if(publishedReport!=null){
			AnalyzerReport report = publishedReport.getReport();
			HashMap<String , Object> values = new HashMap<String , Object>();
			values.put("report", report) ;
			values.put("filters", report.getFilters()) ;
			try {
				for(AnalyzerReportModel model : report.getModel()){
					
						model.setReportData(RivuTools.getReportData(report , new R3Request() , model , Integer.parseInt(params[1].trim()), Integer.parseInt(params[2].trim()))) ;
						values.put("reportData", model.getReportData()) ;
						values.put("reportModel", model) ;
					
				}
				String reportViewData = TempletTools.getTemplet(
						(SearchResultTemplet) RivuDataContext.getService().getIObjectByPK(SearchResultTemplet.class, "402881e43ab07e65013ab080e4c65002"), values) ;
				result = reportViewData ;
			} catch (Exception e) {
				e.printStackTrace();
				result = matchers.group(0);
			}
		}else{
			result = matchers.group(0);
		}
		return result;
	}
	
	public static Function getFunction(String functionstr){
		Function function = null;
		if(functionstr.startsWith("date(")){
			function = new DateFunction();
		}
		return function;
	}
	/**
	 * 处理表达式 ， 使用 {}包含的 表达式
	 * @param content
	 * @param taskReportInfo
	 * @param processhtml
	 * @return
	 */
	public static String processExpressContent(String content , TaskReportInfo taskReportInfo , boolean processhtml){
		/**
		 * 表格替换完毕
		 */
		StringBuffer strb = new StringBuffer();
		Pattern pattern = Pattern.compile("(\\{[\\S\\s]*?\\})") ;
		Matcher matchers = pattern.matcher(content) ;
		int strindex = 0 ;
		while(matchers.find()){
			if(matchers.groupCount()>=1){
				String param = matchers.group(1).replaceAll("<[\\S\\s]*?>", "").replaceAll("[\\{\\}]*", "").replaceAll(",", "");
				strb.append(content.substring(strindex , matchers.start())).append(AviatorEvaluator.execute(param)) ;
				strindex = matchers.end() ;
			}
		}
		strb.append(content.substring(strindex)) ;
		return strb.toString() ;
	}
	
	/**
	 * 处理表格
	 * @param content
	 * @param taskReportInfo
	 * @param includehtml
	 * @return
	 */
	public static String processContentTable(String content , TaskReportInfo taskReportInfo , boolean includehtml){
		if(includehtml){
			Document document = Jsoup.parse(content) ;
			if(document.select("body")!=null){
				document.select("body").attr("style" , "font-family:'Microsoft Yahei','Helvetica','Simsun','Arial';font-size:12px;"+document.select("body").attr("style"));
			}
			Elements tableElements = document.select("table");
			if(tableElements.hasText()){
				for(Element table : tableElements){
					Elements trElements = table.select("tr");
					Elements targetElements = new Elements() ;
					Elements lastProcessTDs = null ;
					for(Element tr : trElements){
						Elements tdElements = tr.getElementsByTag("td") ;
						boolean finddim = false ;
						/**
						 * 用于记录表格中的 维度选择
						 */
						List<List<Object>> targetList = new ArrayList<List<Object>>() ;	//渲染的 最终的 数据目标 ， 类似于 ReportData 
						List<List<ValueData>> dataList = new ArrayList<List<ValueData>>() ;	//需要渲染的 数据 ， 临时对象
						int rows = 1 ;
						/**
						 * 需要对TD进行三次遍历， 第一次遍历 计算出 维度 成员 并且找到所有符合条件的 指标值
						 */
						for(Element td : tdElements){
							td.attr("style","border:1px solid #dddddd;"+td.attr("style")) ;
							/**
							 * 每一个TD对应一个 list，如果TD无需要替换的内容，则不作任何处理
							 */
							List<Object> tdList = new ArrayList<Object>();
							Pattern pattern = Pattern.compile("(\\[[\\S\\s]*?\\])") ;
							Matcher matchers = pattern.matcher(td.text()) ;
							if(matchers.find()){
								if(matchers.groupCount()>=1){
									String param = matchers.group(1).replaceAll("<[\\S\\s]*?>", "").replaceAll("[\\[\\]]*", "");
									/**
									 * param即为需要替换的参数
									 */
									String[] levels = param.split("\\.") ;
									/**
									 * 维度处理，必须要按顺序，否则数据会乱
									 */
									if(levels.length>=3){
										if(levels[2].startsWith("&")){
											/**
											 * 找到维度，需要对表格对象进行渲染填充，如果未找到维度，则不做任何处理，只交给下一个环节进行处理即可（直接返回）
											 */
											finddim = true ;
											AnalyzerReportModel model = getProcessReportModel(taskReportInfo , levels[0] , levels[1]) ;
											String dimtitle = levels[2].substring(1) ;
											int dimindex = -1 ;
											for(FirstTitle title : model.getReportData().getRow().getFirstTitle()){
												if(title.getRename()!=null ? dimtitle.equals(title.getRename()) : dimtitle.equals(title.getName())){
													/**
													 * 先找到 维度的 位置
													 */
													dimindex = model.getReportData().getRow().getFirstTitle().indexOf(title) ;
													break ;
													
												}
											}
											if(dimindex>=0){
												/**
												 * 找到 DIM的位置后 在根据位置找到 level
												 */
												List<Level> titleList = model.getReportData().getRow().getTitle().get(dimindex) ;
												boolean firstLevel = targetList.size() == 0 ;
												if(levels.length == 3){
													for(Level level : titleList){
														/**
														 * 加入条件 ， 当前 level 的name 和 parent 以及，parent.parent.... 必须是在 targetList里的
														 */
														if(inLevelList(targetList , level) || firstLevel ){
															if(level.getParent() == null){
																continue;
																
															}
															
															if(level.getParent().getChilderen()==null || level.getParent().getChilderen().size() == 0){
																dataList.add(level.getParent().getValueData()) ;
															}
															level.setRowspan(1) ;
															level.setColspan(1) ;
															level.setModel(model.getId()) ;
															tdList.add(level) ;
														}
													}
												}else if(levels.length == 4){
													String[] members = levels[3].split(",") ; //多个成员，以逗号分隔的
													for(String member : members){
														for(Level level : titleList){
															if(member.equals(level.getName())){
																/**
																 * 加入条件 ， 当前 level 的name 和 parent 以及，parent.parent.... 必须是在 targetList里的
																 */
																if(inLevelList(targetList , level) || firstLevel ){
																	level.setModel(model.getId()) ;
																	tdList.add(level) ;
																	if(level.getParent().getChilderen()==null || level.getParent().getChilderen().size()==0){
																		dataList.add(level.getParent().getValueData()) ;
																	}
																	level.setRowspan(1) ;
																	level.setColspan(1) ;
																}
//																break ;
															}
														}
													}
												}
											}else{
												td.text("");
											}
										}else{	//处理指标数据 ， 此时 dataList 已经填充完毕，已经有值了
											String measureName = levels[2] ;
											if(dataList.size()>0){
//												boolean foundMeasure = false ;
												for(int i=0 ; i<dataList.size() ; i++){
													for(ValueData valueData : dataList.get(i)){
														if(valueData.getName().equals(measureName) || (measureName.matches("[\\d]{1,}") && Integer.parseInt(measureName) == dataList.get(i).indexOf(valueData)) ){
															tdList.add(valueData) ;
//															foundMeasure = true ;
															break ;
														}
													}
												}
												/**
												 * 设置了指标信息，但在 ReportData里无指标内容，交回给 内容填充
												 */
//												if(!foundMeasure){
//													td.text("");
//												}
											}
										}
									}
								}
							}
							/**
							 * 获取需要最终渲染的 表格行数
							 */
							rows = dataList.size() ;
							targetList.add(tdList) ;
						}
						if(!finddim){
							targetElements.add(tr) ;
						}else{
							/**
							 * 找到了 DIM和自动填充的 数据值， 需要进行渲染数据，即使用  levelList来进行渲染 
							 * 以 tdElements 为依据来渲染，渲染模式 和  ReportData 渲染模式相同，但需要使用 td 的已设定的 数据格式
							 */
							/**
							 * 
							 */
							for(int i=0 ; i<rows ; i++){
								Element targetTr = new Element(tr.tag(), tr.baseUri()) ;
								targetElements.add(targetTr) ;
								for(int col =0 ; col< targetList.size() ; col++){
									Element td = tdElements.get(col) ;
									if(lastProcessTDs!=null && lastProcessTDs.size() == tdElements.size() && lastProcessTDs.get(col)!=null && lastProcessTDs.get(col).attr("data-rowspan")!=null){
										if(lastProcessTDs.get(col).attr("data-rowspan").length()>0 && Integer.parseInt(lastProcessTDs.get(col).attr("data-rowspan"))>1){
											td.attr("data-rowspan", lastProcessTDs.get(col).attr("data-rowspan")) ;
										}
									}
									String datarowspan = td.attr("data-rowspan");
									if(datarowspan!=null && datarowspan.length()>0 && Integer.parseInt(datarowspan) > 1){
										td.attr("data-rowspan", String.valueOf(Integer.parseInt(datarowspan)-1)) ;
									}else{
										Object value = getLevelOrMeasureValue(targetList, i, col) ;
										td.removeAttr("data-rowspan") ;
										Element targetTd = td.clone() ;
										if(targetList.get(col).size()>0){
											if(value instanceof Level){
												Level level = (Level) value ;
												if(level.getRowspan()>1){
													targetTd.attr("rowspan", String.valueOf(level.getRowspan()-1)) ;
													td.attr("data-rowspan", String.valueOf(level.getRowspan()-1)) ;
												}
											}
		
											if(value !=null ){
												targetTd.text(value.toString()) ;
											}
										}else{
											targetTd.attr("rowspan", String.valueOf(rows)) ;
											td.attr("data-rowspan", String.valueOf(rows)) ;
										}
										targetTr.appendChild(targetTd) ;
									}
								}
								targetElements.add(targetTr) ;
							}
						}
						lastProcessTDs = tdElements ;
					}
					table.empty() ;
					for(Element tr : targetElements){
						table.appendChild(tr) ;
					}
					table.attr("style" , "border-collapse: collapse;"+table.attr("style")) ;
				}
				content = document.toString() ;
			}
			
//			document.append("<style>td , th{border: 1px solid #DDD;}table{border-collapse: collapse;}</style>") ;
			
		}
		return content ;
	}
	/**
	 * 
	 * @param targetList
	 * @param rowinx
	 * @return
	 */
	public static Object getLevelOrMeasureValue(List<List<Object>> targetList , int rowinx , int colindex){
		List<Object> tdList = targetList.get(colindex) ;
		Object value = null ; 
		int rowspan = 0 ;
		for(int i=0 ; i<tdList.size(); i++){
			if(tdList.get(i) instanceof Level){
				/**
				 * 计算合并单元格以后的 单元格位置
				 */
				Level level = (Level) tdList.get(i) ;
				if(rowspan == rowinx){
					value = level ;
					break ;
				}
				if(level.getRowspan()>1){
					rowspan += level.getRowspan()-1 ;
				}else{
					rowspan += level.getRowspan() ;
				}
			}else{
				ValueData valueData = (ValueData) tdList.get(rowinx) ;
				value = valueData.getValueStyle()!=null ? valueData.getValueStyle() : valueData.getForamatValue() ;
				break ;
			}
		}
		return value ;
	}
	/**
	 * 判断 当前维度成员的 父级在已选列表中
	 * @param trList
	 * @param curLevel
	 * @return
	 */
	public static boolean inLevelList(List<List<Object>> trList , Level curLevel){
		/**
		 * 从 curLevel的parent的parent开始找 ，直到找到 parent == null
		 */
		boolean inLevel = false ;
		for(int i = trList.size() ; i>0 ; i--){
			List<Object> tdList = trList.get(i-1) ;
			if(tdList.size()>0 && tdList.get(0) instanceof Level){
				boolean findDimInList = false ;
				for(Object data : tdList){
					Level level = (Level) data ;
					inLevel = false ;
					Level parent = curLevel ;
					while((parent = parent.getParent())!=null){
						if(parent.getDimname()!=null && parent.getDimname().equals(level.getParent().getDimname())){
							if(parent.getName().equals(level.getName()) && parent.getModel().equals(level.getModel())){
								findDimInList = true ;
								if(curLevel.getParent().getChilderen()==null || curLevel.getParent().getChilderen().size() == 0){
									level.setRowspan(level.getRowspan()+1) ;//找到一次，即表示 合并单元格+1
								}
								break ;
							}
						}
					}
					if(findDimInList){
						break ;
					}
				}
				inLevel = findDimInList ;
				if(findDimInList == false){
					break ;
				}
			}
		}
		return inLevel ;
	}
	public static List<String> processAppendix(TaskReportInfo taskReportInfo,JobDetail job)throws Exception{
		List<String> filenames = new ArrayList<String>();
		ExportFile exportFile = null ;
		int reportCount = 0;
		if(taskReportInfo!=null && taskReportInfo.getReportList().size()>0){
//			List<TaskReport> reportlist = new ArrayList<TaskReport>();
//			for (TaskReport taskReport : taskReportInfo.getReportList()) {//如果有重复的去掉
//				boolean flag = true;
//				for (int i = 0; i < reportlist.size(); i++) {
//					if(reportlist.get(i).getPublishedReport().getName().equals(taskReport.getPublishedReport().getName())){
//						flag=false;
//						break;
//					}
//				}
//				if(flag){
//					reportlist.add(taskReport);
//				}
//			}
			
			String excelfilename = RivuDataContext.DATA_DIR.toString()+"/temp/"+job.getName()+".xlsx";
    		filenames.add(excelfilename);
    		exportFile = new RivuExcelUtil();
    		File file = new File(excelfilename);
    		FileOutputStream fos = new FileOutputStream(file);
    		exportFile.setOut(fos);
			try {
				for(TaskReport taskReport : taskReportInfo.getReportList()){
					if("user".equals(taskReport.getUserDefined())){//邮件自定义的报表不导出
						continue;
					}
					reportCount++;
					int count = 0;
					exportFile.createSheet(taskReport.getPublishedReport().getName());
					exportFile.setRowNum(0);
					AnalyzerReport analyzerReport = taskReport.getPublishedReport().getReport() ;
					AnalyzerReportModel reportModel = null ;
					if(analyzerReport.getModel().size()>0){
						for(AnalyzerReportModel model : analyzerReport.getModel()){
							if(count>0){
								exportFile.setRowNum(exportFile.getRowNum()+2);
							}
							reportModel = model ;
							reportModel.setReportid(taskReport.getPublishedReport().getId());
							reportModel.setDisplaytitle(true) ;
							reportModel.setPublishtype("modelpublish") ;
							reportModel.setIsexport(true);
							
							exportFile.setModel(reportModel);
							exportFile.setPage(1);
							exportFile.setReport(analyzerReport);
							reportModel.setExport(exportFile);
							exportFile.setHeadTitle(reportModel.getName()!=null  && reportModel.getName().length()>0 ? reportModel.getName() : taskReport.getPublishedReport().getName()) ;
							ReportData reportData = RivuTools.getReportData(analyzerReport , null , model,1, 20);
							
							if(RivuDataContext.DataBaseTYPEEnum.HIVE.toString().equals(reportModel.getDbType())){
		    					reportModel.getExport().setReportData(reportData);
								reportModel.getExport().createFile(false);
								
		    				}else{
		    					reportModel.getExport().setReportData(reportData);
								reportModel.getExport().createFile(true);
		    				}
							
							count++;
						}
					}
				
				}
				exportFile.close();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				throw e;
			}finally{
				
				fos.close();
			}//
			
		}
		if(reportCount>0){
			return filenames;
		}else{
			FileUtil.deleteFiles(filenames);//删除临时文件
			return null;
		}
		
	}
	
	public static String getServerName(){
		StringBuffer strb = new StringBuffer();
		RuntimeData runtime = new RuntimeData() ;
		strb.append(runtime.getHostname()).append(":").append(runtime.getPort()) ;
		return strb.toString() ;
	}
	
	
	/*
	 * AviatorEvaluator测试
	 * 
	 */
	public static void main(String[] args) {
		System.out.println(AviatorEvaluator.execute("(337550.00+326450.00)/(102+89)"));
	}
	
	
	public static boolean outputLog(String level , String orgi){
		boolean log = false ;
		String value =  (String) CacheHelper.getDistributedDictionaryCacheBean().getCacheObject("logrec.logLevel.system.level", orgi) ;
		if(value!=null){
			if(value.equals("debug")){
				log = true ;
			}else if(value!=null && value.equals("info")){
				if(!level.toLowerCase().equals("debug")){
					log = true ;
				}
			}else if(value.equals("warn")){
				if(level.toLowerCase().equals("error") || level.equals("warn")){
					log = true ;
				}
			}else if(value.equals("error")){
				if(level.toLowerCase().equals("error")){
					log = true ;
				}
			}
		}
		return log ;
	}
	
	public static void processPersistenceLog(BlockingQueue<Object> monitorEventQueue){
		if(monitorEventQueue.size()>1000){
			monitorEventQueue.clear();
		}
	}
	/**
	 * 导出文件，如果当前任务正在执行，则返回执行的 JobDetail，如果任务已经执行完毕，则返回Null。如果无任务，则创建一个新的 任务，然后返回，如果返回值为Null，则表示任务已经执行完毕，直接
	 * 从文件系统中获取即可
	 * @return
	 */
	public synchronized static JobDetail createExportJobDetail(String name , AnalyzerReport analyzerReport , HttpServletRequest request, AnalyzerReportModel reportModel , User user , String queryTextID ,String wt,boolean iscreate){
		JobDetail job = null ;
		/**
		 * 第一步，检查 任务是否在  任务队列里，第二部，检查文件系统里是否存在已执行完毕的文件
		 */
		List<JobDetail> jobDetailList = RivuDataContext.getService().findPageByCriteria(DetachedCriteria.forClass(JobDetail.class).add(Restrictions.eq("id", queryTextID))) ;
		if(iscreate&&jobDetailList.size()==0 && !hasExportFile(analyzerReport, request, reportModel, user.getOrgi(), queryTextID) && (job = getRunningJob(user.getOrgi(), queryTextID)) == null){
			job = new JobDetail() ;
			job.setId(queryTextID) ;
			job.setName(name+"_"+user.getUsername()+"_导出任务");
			job.setOrgi(user.getOrgi());
			job.setTasktype(RivuDataContext.TaskTypeEnum.EXPORT.toString());
			job.setUserid(user.getId());
			job.setUsername(user.getUsername());
			job.setEmail(user.getEmail());
			job.setNextfiretime(new Date()) ;
			job.setMemo(wt) ;
			job.setUsearea(request.getParameter("total"));

			job.setDataid(reportModel.getId()) ;				//一次性任务，执行完毕后即可删除该任务
			job.setTaskinfo(JSON.toJSONString(analyzerReport)) ;
			job.setTaskid("RUN_ONCE");
			job.setTaskstatus("1");//立即开始执行
			job.setFetcher(true);
			job.setPause(false);
			job.setPlantask(false);
			job.setPriority(3) ;
			job.setDicid(queryTextID);
			job.setNickname(user.getNickname());
			RivuDataContext.getService().saveIObject(job) ;
		}
		if(jobDetailList.size()>0){
			Map<String, Object> jobDetailMap = RivuDataContext.getClusterInstance().get(RivuDataContext.DistributeEventEnum.JOBDETAIL.toString());
			job = (JobDetail) jobDetailMap.get(queryTextID);
			if(job==null){
				jobDetailMap = RivuDataContext.getClusterInstance().get(RivuDataContext.DistributeEventEnum.RUNNINGJOB.toString());
				job = (JobDetail) jobDetailMap.get(queryTextID);
				if(job==null){
					job = jobDetailList.get(0) ;
				}
			}
		}
		return job ;
	}
	/**
	 * 检查是否有导出的文件存在
	 * @param report
	 * @param request
	 * @param reportModel
	 * @param user
	 * @param queryTextID
	 * @return
	 */
	public static boolean hasExportFile(AnalyzerReport analyzerReport , HttpServletRequest request, AnalyzerReportModel reportModel ,String orgi, String queryTextID){
		return getExportFile(analyzerReport, request, reportModel, orgi, queryTextID) != null ;
	}
	/**
	 * 获取导出的文件，根据导出文件的 创建时间检查文件是否过期，如果过期则忽略，过期时间默认为1天
	 * @param report
	 * @param request
	 * @param reportModel
	 * @param user
	 * @param queryTextID
	 * @return
	 */
	public static File getExportFile(AnalyzerReport analyzerReport , HttpServletRequest request, AnalyzerReportModel reportModel , String orgi , String queryTextID){
		return getExportFile(orgi , queryTextID) ;
	}
	
	/**
	 * 获取导出的文件，根据导出文件的 创建时间检查文件是否过期，如果过期则忽略，过期时间默认为1天
	 * @param report
	 * @param request
	 * @param reportModel
	 * @param user
	 * @param queryTextID
	 * @return
	 */
	public static File getExportFile(String orgi , String queryTextID){
		File exportFile = getExportFileWithOutTimeOut(orgi, queryTextID);
		if(exportFile!=null && exportFile.exists()){//&& exportFile.length()>0
			long lastModifiedTime = exportFile.lastModified() ; //最后修改时间应该从 JOB中获取，有些任务导出时间很长，超过1小时，如果从 文件属性中获取，则有可能导出完成即失效
			/**
			 * 
			 */
			File exportJobFile = getExportJob(orgi, queryTextID) ;
			if(exportJobFile.exists()){
				lastModifiedTime = exportJobFile.lastModified() ;
				String exportFileTimes = (String) CacheHelper.getDistributedDictionaryCacheBean().getCacheObject("com.rivues.file.export.timeout", orgi) ;
				long times = 1000 * 60 * 30 ;	//默认有效期为 30分钟
				if(exportFileTimes!=null && exportFileTimes.matches("[\\d]{1,}")){
					times = Long.parseLong(exportFileTimes)/1000 ; //单位是秒
				}
				if((new Date().getTime() - lastModifiedTime)>=times){
					if(exportFile.exists()){
						exportFile.delete(); 	//先删除文件
					}
					exportFile = null ;
				}
			}else{
				exportFile = null ;
			}
		}else{
			exportFile = null ;
		}
		return exportFile ;
	}
	
	/**
	 * 获取导出的文件，根据导出文件的 创建时间检查文件是否过期，如果过期则忽略，过期时间默认为1天
	 * @param report
	 * @param request
	 * @param reportModel
	 * @param user
	 * @param queryTextID
	 * @return
	 */
	public static File getExportFileWithOutTimeOut(String orgi , String queryTextID){
		return new File(getDefaultExportFilePath(orgi)  , queryTextID);
	}
	
	
	/**
	 * 获取导出的文件，根据导出文件的 创建时间检查文件是否过期，如果过期则忽略，过期时间默认为1天
	 * @param report
	 * @param request
	 * @param reportModel
	 * @param user
	 * @param queryTextID
	 * @return
	 */
	public static File getExportJob(String orgi , String queryTextID){
		return new File(getDefaultExportJobPath(orgi)  , queryTextID+".job");
	}
	/**
	 * 
	 * @param analyzerReport
	 * @param request
	 * @param reportModel
	 * @param orgi
	 * @param queryTextID
	 * @return
	 */
	public static String getExportFileName(AnalyzerReport analyzerReport , HttpServletRequest request, AnalyzerReportModel reportModel , String orgi , String queryTextID){
		return queryTextID;
	}
	/**
	 * 获取当前正在运行的 JobDetail
	 * @param report
	 * @param request
	 * @param reportModel
	 * @param user
	 * @param queryTextID
	 * @return
	 */
	public static JobDetail getRunningJob(String orgi , String queryTextID){
		Map<String, Object> jobDetailMap = RivuDataContext.getClusterInstance().get(RivuDataContext.DistributeEventEnum.JOBDETAIL.toString());
		Map<String, Object> runningJobMap = RivuDataContext.getClusterInstance().get(RivuDataContext.DistributeEventEnum.RUNNINGJOB.toString());
		JobDetail jobDetail = null ;
		if((jobDetail = (JobDetail) jobDetailMap.get(queryTextID)) == null){
			jobDetail = (JobDetail) runningJobMap.get(queryTextID) ;
		}
		return jobDetail ;
	}
	
	public static boolean hasNAS(String orgi){
		return CacheHelper.getDistributedDictionaryCacheBean().getCacheObject("com.rivues.file.export", orgi)!=null ;
	}
	/**
	 * 获取导出文件的导出目录
	 * @param orgi
	 * @return
	 */
	public static File getDefaultExportFilePath(String orgi){
		String exportFilePath = (String) CacheHelper.getDistributedDictionaryCacheBean().getCacheObject("com.rivues.file.export", orgi) ;
		File exportFile = null ;
		if(exportFilePath==null){
			exportFile = new File(RivuDataContext.DATA_DIR , "export/data") ;
		}else{
			exportFile = new File(exportFilePath+"/data");
		}
		if(!exportFile.exists()){
			exportFile.mkdirs() ;
		}
		return exportFile ;
	}
	
	/**
	 * 获取导出文件的导出目录
	 * @param orgi
	 * @return
	 */
	public static long getMaxExportFileStorageSize(String orgi){
		String maxStorageSize = (String) CacheHelper.getDistributedDictionaryCacheBean().getCacheObject("com.rivues.file.export.storage", orgi) ;
		long max = Long.MAX_VALUE ;
		if(maxStorageSize!=null && maxStorageSize.matches("[\\d]{1,}")){
			max = Long.parseLong(maxStorageSize) ;
		}
		return max ;
	}
	
	
	
	/**
	 * 获取导出文件的导出目录
	 * @param orgi
	 * @return
	 */
	public static File getDefaultExportJobPath(String orgi){
		String exportFilePath = (String) CacheHelper.getDistributedDictionaryCacheBean().getCacheObject("com.rivues.file.export", orgi) ;
		File exportFile = null ;
		if(exportFilePath==null){
			exportFile = new File(RivuDataContext.DATA_DIR , "export/job") ;
		}else{
			exportFile = new File(exportFilePath+"/job");
		}
		if(!exportFile.exists()){
			exportFile.mkdirs() ;
		}
		return exportFile ;
	}
	
	public static String getDefaultBackupFilePath(String orgi){
		String backupFilePath = (String) CacheHelper.getDistributedDictionaryCacheBean().getCacheObject("com.rivues.file.backup", orgi) ;
		String backupFile = null ;
		if(backupFilePath==null){
			backupFile = RivuDataContext.DATA_DIR.toString()+"/backups/";
		}else{
			backupFile = backupFilePath;
		}
		return backupFile ;
	}

	public static String getDicExportCacheSize(String reportid,String cachename,String orgi)throws Exception{
		String result = null;
		PublishedReport report = null;
		try {
			report = ReportFactory.getReportInstance().getReportByID(RivuDataContext.getUser(new R3Request()), orgi, reportid) ;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			if(report==null)return result;
		}
		String id = report.getDicid();
		if("0".equals(id)){
			Object cachesize = CacheHelper.getDistributedDictionaryCacheBean().getCacheObject(cachename+"0", orgi);
			if(cachesize==null) return null;
			else return cachesize.toString();
		}
		
		List<DataDic> diclist = RivuDataContext.getService().findAllByCriteria(DetachedCriteria.forClass(DataDic.class).add(Restrictions.eq("orgi",orgi)));
		DataDic parent = null ;
		while(parent==null){
			for(DataDic type : diclist){
				if(type.getId().equals(id)){
					parent = type ;
					id = parent.getParentid();
					break ;
				}
			}
			if(parent!=null){
				Object cachesize = CacheHelper.getDistributedDictionaryCacheBean().getCacheObject(cachename+parent.getId(), orgi);
				if(cachesize!=null){
					result = cachesize.toString();
					break;
				}
				parent = null;
			}else{
				break ;
			}
		}
		return result;
	}

	/**
	 * 
	 * @param jobDetail
	 * @return
	 */
	public static String status(JobDetail jobDetail){
		long times =  (System.currentTimeMillis() - jobDetail.getReport().getStart())/1000 ;
		if(times==0){
			times = 1;
		}
		return new StringBuffer().append("已处理：").append(jobDetail.getReport().getAtompages().intValue()).append(", 错误：").append(jobDetail.getReport().getErrors()).append("，处理速度：").append(jobDetail.getReport().getAtompages().intValue() / times).append("条/秒，线程数：").append(jobDetail.getReport().getThreads()).append(jobDetail.getReport().getDetailmsg()!=null ? "，详细信息："+jobDetail.getReport().getDetailmsg() : "").toString();
	}
	/**
	 * 获取系统配置的导出参数。如果未配置参数，则默认最大一次导出 10000条
	 * @param param
	 * @param reportid
	 * @param orgi
	 * @return
	 */
	public static String getReportConfigureParam(String param , String reportid , String orgi)throws Exception{
		Object cachesize = CacheHelper.getDistributedDictionaryCacheBean().getCacheObject(param+"."+reportid, orgi);
		if(cachesize==null){
			cachesize = RivuTools.getDicExportCacheSize(reportid, param+".", orgi);
		}
		if(cachesize==null){
			cachesize = CacheHelper.getDistributedDictionaryCacheBean().getCacheObject(param, orgi);
		}
		return cachesize!=null ? cachesize.toString() : "" ;
	}
	
	/**
	 * 
	 * @param report
	 * @return
	 */
	public static String appendFilterSqlWhere(List<ReportFilter> filters,ReportFilter filter,Cube cube){
		StringBuffer wherestr = new StringBuffer();
		if(cube!=null&&filter!=null&&filter.getParentFilter()!=null&&filters!=null&&filters.size()>0){
			String id = filter.getId();
			ReportFilter parent = null ;
			while(parent==null){
				for(ReportFilter type : filters){
					if(type.getId().equals(id)){
						parent = type.getParentFilter() ;
						if(type.getParentFilter()!=null){
							id = type.getParentFilter().getId();
							break ;
						}else{
							return wherestr.toString();
						}
						
					}
				}
				if(parent!=null){
					if(!org.apache.commons.lang.StringUtils.isBlank(parent.getCurvalue())){
						if(wherestr.length()>0){
							wherestr.append(" AND ");
						}
						for(Dimension dimension : cube.getDimension()){
		    				for(CubeLevel level : dimension.getCubeLevel()){
		    					if(level.getId().equals(parent.getDataid())){
		    						wherestr.append(level.getRealCol(cube)).append(" = '").append(parent.getCurvalue()).append("'");
		    						break ;
		    					}
		    				}
		    			}
					}
					
					parent = null;
				}else{
					break ;
				}
			}
			
		}
		
		return wherestr.toString();
	}
	
	
	public static ReportOperations createReportOptions(PublishedReport report,User user){
		ReportOperations operation = new ReportOperations();
		operation.setCreatetime(new Date());
		operation.setName(report.getName());
		operation.setFlowid(System.currentTimeMillis());
		operation.setReportcontent(report.getReportcontent());
		operation.setUserid(user.getId());
		operation.setReportid(report.getId());
		return operation;
	}
	
	
	public static boolean checkReportIsChange(PublishedReport oldrpt,PublishedReport newrpt){
		
		AnalyzerReport old_analyzerReport = oldrpt.getReport() ;
    	AnalyzerReportModel old_reportModel = null ;
    	if(old_analyzerReport.getModel().size()>0){
    		for(AnalyzerReportModel model : old_analyzerReport.getModel()){
    			old_reportModel = model ;
				break;
    		}
    	}
    	
    	AnalyzerReport new_analyzerReport = newrpt.getReport() ;
    	AnalyzerReportModel new_reportModel = null ;
    	if(new_analyzerReport.getModel().size()>0){
    		for(AnalyzerReportModel model : new_analyzerReport.getModel()){
    			new_reportModel = model ;
				break;
    		}
    	}
    	if(new_reportModel==null||old_reportModel==null){
    		return false;
    	}
    	
    	if((old_reportModel.getColdimension()!=null&&!old_reportModel.getColdimension().equals(new_reportModel.getColdimension()))
    			||(new_reportModel.getColdimension()!=null&&!new_reportModel.getColdimension().equals(old_reportModel.getColdimension()))){
    		return true;
    	}
    	if((old_reportModel.getMeasure()!=null&&!old_reportModel.getMeasure().equals(new_reportModel.getMeasure()))
    			||(new_reportModel.getMeasure()!=null&&!new_reportModel.getMeasure().equals(old_reportModel.getMeasure()))){
    		return true;
    	}
    	if((old_reportModel.getRowdimension()!=null&&!old_reportModel.getRowdimension().equals(new_reportModel.getRowdimension()))
    			||(new_reportModel.getRowdimension()!=null&&!new_reportModel.getRowdimension().equals(old_reportModel.getRowdimension()))){
    		return true;
    	}
    	if((old_reportModel.getStylestr()!=null&&!old_reportModel.getStylestr().equals(new_reportModel.getStylestr()))
    			||(new_reportModel.getStylestr()!=null&&!new_reportModel.getStylestr().equals(old_reportModel.getStylestr()))){
    		return true;
    	}
    	
    	if((old_reportModel.getQuerytext()!=null&&!old_reportModel.getQuerytext().equals(new_reportModel.getQuerytext()))
    			||(new_reportModel.getQuerytext()!=null&&!new_reportModel.getQuerytext().equals(old_reportModel.getQuerytext()))){
    		return true;
    	}
    	if((old_reportModel.getColformatstr()!=null&&!old_reportModel.getColformatstr().equals(new_reportModel.getColformatstr()))
    			||(new_reportModel.getColformatstr()!=null&&!new_reportModel.getColformatstr().equals(old_reportModel.getColformatstr()))){
    		return true;
    	}
    	
    	if((old_reportModel.getRowformatstr()!=null&&!old_reportModel.getRowformatstr().equals(new_reportModel.getRowformatstr()))
    			||(new_reportModel.getRowformatstr()!=null&&!new_reportModel.getRowformatstr().equals(old_reportModel.getRowformatstr()))){
    		return true;
    	}
    	
    	if(old_analyzerReport.getFilters()!=null&&old_analyzerReport.getFilters()!=null
    			&&old_analyzerReport.getFilters().size()!=new_analyzerReport.getFilters().size()){
    		return true;
    	}
    	
    	for(ReportFilter old_reportFilter : old_analyzerReport.getFilters()){
    		for(ReportFilter new_reportFilter : new_analyzerReport.getFilters()){
    			if(old_reportFilter.getId().equals(new_reportFilter.getId())){
    				if((old_reportFilter.getDefaultvalue()!=null&&!old_reportFilter.getDefaultvalue().equals(new_reportFilter.getDefaultvalue()))
        	    			||(new_reportFilter.getDefaultvalue()!=null&&!new_reportFilter.getDefaultvalue().equals(old_reportFilter.getDefaultvalue()))){
        	    		return true;
        	    	}
    				
    				if((old_reportFilter.getMustvalue()!=null&&!old_reportFilter.getMustvalue().equals(new_reportFilter.getMustvalue()))
        	    			||(new_reportFilter.getMustvalue()!=null&&!new_reportFilter.getMustvalue().equals(old_reportFilter.getMustvalue()))){
        	    		return true;
        	    	}
    				if((old_reportFilter.getRequestvalue()!=null&&!old_reportFilter.getRequestvalue().equals(new_reportFilter.getRequestvalue()))
        	    			||(new_reportFilter.getRequestvalue()!=null&&!new_reportFilter.getRequestvalue().equals(old_reportFilter.getRequestvalue()))){
        	    		return true;
        	    	}
    				
    				if((old_reportFilter.getRequeststartvalue()!=null&&!old_reportFilter.getRequeststartvalue().equals(new_reportFilter.getRequeststartvalue()))
        	    			||(new_reportFilter.getRequeststartvalue()!=null&&!new_reportFilter.getRequeststartvalue().equals(old_reportFilter.getRequeststartvalue()))){
        	    		return true;
        	    	}
    				if((old_reportFilter.getRequestendvalue()!=null&&!old_reportFilter.getRequestendvalue().equals(new_reportFilter.getRequestendvalue()))
        	    			||(new_reportFilter.getRequestendvalue()!=null&&!new_reportFilter.getRequestendvalue().equals(old_reportFilter.getRequestendvalue()))){
        	    		return true;
        	    	}
    				
    				if((old_reportFilter.getName()!=null&&!old_reportFilter.getName().equals(new_reportFilter.getName()))
        	    			||(new_reportFilter.getName()!=null&&!new_reportFilter.getName().equals(old_reportFilter.getName()))){
        	    		return true;
        	    	}
    				if((old_reportFilter.getCode()!=null&&!old_reportFilter.getCode().equals(new_reportFilter.getCode()))
        	    			||(new_reportFilter.getCode()!=null&&!new_reportFilter.getCode().equals(old_reportFilter.getCode()))){
        	    		return true;
        	    	}
    				
    				if((old_reportFilter.getModeltype()!=null&&!old_reportFilter.getModeltype().equals(new_reportFilter.getModeltype()))
        	    			||(new_reportFilter.getModeltype()!=null&&!new_reportFilter.getModeltype().equals(old_reportFilter.getModeltype()))){
        	    		return true;
        	    	}
    				if((old_reportFilter.getConvalue()!=null&&!old_reportFilter.getConvalue().equals(new_reportFilter.getConvalue()))
        	    			||(new_reportFilter.getConvalue()!=null&&!new_reportFilter.getConvalue().equals(old_reportFilter.getConvalue()))){
        	    		return true;
        	    	}
    				
    				if((old_reportFilter.getValuefiltertype()!=null&&!old_reportFilter.getValuefiltertype().equals(new_reportFilter.getValuefiltertype()))
        	    			||(new_reportFilter.getValuefiltertype()!=null&&!new_reportFilter.getValuefiltertype().equals(old_reportFilter.getValuefiltertype()))){
        	    		return true;
        	    	}
    				
    				if((old_reportFilter.getComparetype()!=null&&!old_reportFilter.getComparetype().equals(new_reportFilter.getComparetype()))
        	    			||(new_reportFilter.getComparetype()!=null&&!new_reportFilter.getComparetype().equals(old_reportFilter.getComparetype()))){
        	    		return true;
        	    	}
    				
    			}
    			
        	}
    	}
    	
    	
    	
		return false;
	}
	
	public static String createMobileAccessURL(HttpServletRequest request , String orgi , String reportid){
		StringBuffer strb = new StringBuffer() ;
		strb.append("http://") ;
    	if(request.getServerPort()==80){
    		strb.append(request.getServerName()) ;
    	}else{
    		strb.append(request.getServerName()+":"+request.getServerPort()) ;
    	}
    	strb.append("/").append(orgi).append("/user/report/mobile/").append(reportid).append(".html") ;
    	return strb.toString() ;
	}
	private static String TEXT_FIELD = "\\{([\\S\\s]*?)\\}" ;
	public static String processSystemProperties(String text){
		StringBuffer strb = new StringBuffer() ;
		int start = 0 ;
		Matcher matcher = Pattern.compile(TEXT_FIELD).matcher(text);
		boolean found = false ;
		while((matcher.find()) && (matcher.groupCount() >= 1)) {
			int count = matcher.groupCount() ;
			found = true ;
			for(int i=1 ; i<=count ; i++){
				String key = matcher.group(i) ;
				String value = System.getProperty(key) ;
				strb.append(text.substring(start , matcher.start())).append(value) ;
				start = matcher.end() ;
			}
		}
		if(!found){
			strb.append(text) ;
		}else{
			strb.append(text.substring(start)) ;
		}
		return strb.toString() ;
	}
	
	public static List<TaskReport> sortTaskReports(List<TaskReport> reports){//小到大的排序
		List<TaskReport> taskreports = new ArrayList<TaskReport>();
		String[] names = new String[reports.size()];
		for (int i = 0; i < reports.size(); i++) {
			names[i] = reports.get(i).getPublishedReport().getName();
		}
        String temp = null;
        for(int i = 0;i<names.length;i++){
            for(int j = i;j<names.length;j++){
                if(names[i].compareTo(names[j])>0){
                   //方法一：
                    temp = names[i];
                    names[i] = names[j];
                    names[j] = temp;
                   }

             }
        }
        for (int i = 0; i < names.length; i++) {
			System.out.println(names[i]);
			for (int j = 0; j < reports.size(); j++) {
				if(names[i].equals(reports.get(j).getPublishedReport().getName())){
					taskreports.add(reports.get(j));
					break;
				}
			}
			
		}
        return taskreports;
    }
	
	public static String getValue(String key, String orgi,String defaultValue){
		return (String)CacheHelper.getDistributedDictionaryCacheBean().getCacheObject(key, orgi,defaultValue);
    }
	

	
	public static String formatMicrometer(String text) 
	   { 
	       DecimalFormat df = null; 
	       if(text.indexOf(".") > 0) 
	       { 
	           if(text.length() - text.indexOf(".")-1 == 0) 
	           { 
	                df = new DecimalFormat("###,##0."); 
	           }else if(text.length() - text.indexOf(".")-1 == 1) 
	           { 
	                df = new DecimalFormat("###,##0.0"); 
	           }else 
	           { 
	                df = new DecimalFormat("###,##0.00"); 
	            } 
	       }else  
	       { 
	           df = new DecimalFormat("###,##0"); 
	       } 
	       double number = 0.0; 
	       try { 
	            number = Double.parseDouble(text); 
	       } catch (Exception e) { 
	           return text;
	       } 
	       return df.format(number); 
	    }
	
}